home *** CD-ROM | disk | FTP | other *** search
- /* fog.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Id: fog.c,v 1.9 1995/11/03 22:35:35 brianp Exp $
-
- $Log: fog.c,v $
- * Revision 1.9 1995/11/03 22:35:35 brianp
- * replaced gl_fog_color_vertex with gl_fog_color_vertices
- * replaced gl_fog_index_vertex with gl_fog_index_vertices
- *
- * Revision 1.8 1995/07/20 15:35:11 brianp
- * added type casts to stop warnings with Sun's cc
- *
- * Revision 1.7 1995/06/12 15:41:04 brianp
- * removed debugging printf's
- *
- * Revision 1.6 1995/06/12 15:33:54 brianp
- * changed color arrays to GLubyte
- * check for -eyez in gl_fog_index_pixels
- *
- * Revision 1.5 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.4 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.3 1995/02/27 22:48:50 brianp
- * modified for PB
- *
- * Revision 1.2 1995/02/26 22:58:24 brianp
- * fixed glFogi
- *
- * Revision 1.1 1995/02/24 14:23:03 brianp
- * Initial revision
- *
- */
-
-
- #include <math.h>
- #include <stdlib.h>
- #include "context.h"
- #include "list.h"
- #include "macros.h"
-
-
-
- void gl_fog( GLenum pname, const GLfloat *params )
- {
- GLenum m;
-
- switch (pname) {
- case GL_FOG_MODE:
- m = (GLenum) (GLint) *params;
- if (m==GL_LINEAR || m==GL_EXP || m==GL_EXP2) {
- CC.Fog.Mode = m;
- }
- else {
- gl_error( GL_INVALID_ENUM, "glFog" );
- }
- break;
- case GL_FOG_DENSITY:
- if (*params<0.0) {
- gl_error( GL_INVALID_VALUE, "glFog" );
- }
- else {
- CC.Fog.Density = *params;
- }
- break;
- case GL_FOG_START:
- CC.Fog.Start = *params;
- break;
- case GL_FOG_END:
- CC.Fog.End = *params;
- break;
- case GL_FOG_INDEX:
- CC.Fog.Index = *params;
- break;
- case GL_FOG_COLOR:
- CC.Fog.Color[0] = params[0];
- CC.Fog.Color[1] = params[1];
- CC.Fog.Color[2] = params[2];
- CC.Fog.Color[3] = params[3];
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glFog" );
- }
- }
-
-
-
- void glFogf( GLenum pname, GLfloat param )
- {
- if (CC.ExecuteFlag) {
- gl_fog( pname, ¶m );
- }
- if (CC.CompileFlag) {
- gl_save_fog( pname, ¶m );
- }
- }
-
-
-
- void glFogi( GLenum pname, GLint param )
- {
- GLfloat p;
-
- p = (GLfloat) param;
-
- if (CC.ExecuteFlag) {
- gl_fog( pname, &p );
- }
- if (CC.CompileFlag) {
- gl_save_fog( pname, &p );
- }
- }
-
-
-
- void glFogfv( GLenum pname, const GLfloat *params )
- {
- if (CC.ExecuteFlag) {
- gl_fog( pname, params );
- }
- if (CC.CompileFlag) {
- gl_save_fog( pname, params );
- }
- }
-
-
-
- void glFogiv( GLenum pname, const GLint *params )
- {
- GLfloat p[4];
-
- switch (pname) {
- case GL_FOG_MODE:
- case GL_FOG_DENSITY:
- case GL_FOG_START:
- case GL_FOG_END:
- case GL_FOG_INDEX:
- p[0] = (GLfloat) *params;
- break;
- case GL_FOG_COLOR:
- p[0] = INT_TO_FLOAT( params[0] );
- p[1] = INT_TO_FLOAT( params[1] );
- p[2] = INT_TO_FLOAT( params[2] );
- p[3] = INT_TO_FLOAT( params[3] );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glFogi" );
- return;
- }
- if (CC.ExecuteFlag) {
- gl_fog( pname, p );
- }
- if (CC.CompileFlag) {
- gl_save_fog( pname, p );
- }
- }
-
-
-
- /*
- * Compute the fogged color for an array of vertices.
- * Input: n - number of vertices
- * v - array of vertices
- * color - the original vertex colors
- * Output: color - the fogged colors
- */
- void gl_fog_color_vertices( GLuint n, GLfloat v[][4], GLfloat color[][4] )
- {
- GLuint i;
- GLfloat d;
- GLfloat fogr = CC.Fog.Color[0];
- GLfloat fogg = CC.Fog.Color[1];
- GLfloat fogb = CC.Fog.Color[2];
- GLfloat foga = CC.Fog.Color[3];
-
- switch (CC.Fog.Mode) {
- case GL_LINEAR:
- d = 1.0F / (CC.Fog.End - CC.Fog.Start);
- for (i=0;i<n;i++) {
- GLfloat f = (CC.Fog.End - ABS(v[i][2])) * d;
- f = CLAMP( f, 0.0F, 1.0F );
- color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
- color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
- color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
- color[i][3] = f * color[i][3] + (1.0F-f) * foga;
- }
- break;
- case GL_EXP:
- d = -CC.Fog.Density;
- for (i=0;i<n;i++) {
- GLfloat f = exp( d * ABS(v[i][2]) );
- f = CLAMP( f, 0.0F, 1.0F );
- color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
- color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
- color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
- color[i][3] = f * color[i][3] + (1.0F-f) * foga;
- }
- break;
- case GL_EXP2:
- d = -(CC.Fog.Density*CC.Fog.Density);
- for (i=0;i<n;i++) {
- GLfloat z = ABS(v[i][2]);
- GLfloat f = exp( d * z*z );
- f = CLAMP( f, 0.0F, 1.0F );
- color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
- color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
- color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
- color[i][3] = f * color[i][3] + (1.0F-f) * foga;
- }
- break;
- default:
- abort();
- }
- }
-
-
-
-
-
- /*
- * Compute the fogged color indexes for an array of vertices.
- * Input: n - number of vertices
- * v - array of vertices
- * In/Out: indx - array of vertex color indexes
- */
- void gl_fog_index_vertices( GLuint n, GLfloat v[][4], GLfloat indx[] )
- {
- GLuint i;
- GLfloat d;
-
- switch (CC.Fog.Mode) {
- case GL_LINEAR:
- d = 1.0F / (CC.Fog.End - CC.Fog.Start);
- for (i=0;i<n;i++) {
- GLfloat z = ABS(v[i][2]);
- GLfloat f = (CC.Fog.End - z) * d;
- f = CLAMP( f, 0.0F, 1.0F );
- indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
- }
- break;
- case GL_EXP:
- d = -CC.Fog.Density;
- for (i=0;i<n;i++) {
- GLfloat z = ABS(v[i][2]);
- GLfloat f = exp( d * z );
- f = CLAMP( f, 0.0F, 1.0F );
- indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
- }
- break;
- case GL_EXP2:
- d = -(CC.Fog.Density*CC.Fog.Density);
- for (i=0;i<n;i++) {
- GLfloat z = ABS(v[i][2]);
- GLfloat f = exp( -d * z*z );
- f = CLAMP( f, 0.0F, 1.0F );
- indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
- }
- break;
- default:
- abort();
- }
- }
-
-
-
-
- /*
- * Apply fog to an array of RGBA pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
- */
- void gl_fog_color_pixels( GLuint n, GLint z[], GLubyte red[],
- GLubyte green[], GLubyte blue[], GLubyte alpha[] )
- {
- /* TODO: optimize case when c = 1.0 and d = 0.0 */
- GLfloat d = CC.ProjectionMatrix[14];
- GLfloat c = CC.ProjectionMatrix[10];
- GLfloat winz, ndcz, eyez, f;
- GLuint i;
-
- GLint fog_red = (GLint) (CC.Fog.Color[0] * CC.RedScale);
- GLint fog_green = (GLint) (CC.Fog.Color[1] * CC.GreenScale);
- GLint fog_blue = (GLint) (CC.Fog.Color[2] * CC.BlueScale);
- GLint fog_alpha = (GLint) (CC.Fog.Color[3] * CC.AlphaScale);
-
- switch (CC.Fog.Mode) {
- case GL_LINEAR:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = (CC.Fog.End - eyez) / (CC.Fog.End - CC.Fog.Start);
- f = CLAMP( f, 0.0F, 1.0F );
- red[i] = (GLint) (f * (GLfloat) red[i] + (1.0F-f) * fog_red);
- green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
- blue[i] = (GLint) (f * (GLfloat) blue[i] + (1.0F-f) * fog_blue);
- alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
- }
- break;
- case GL_EXP:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = exp( -CC.Fog.Density * eyez );
- f = CLAMP( f, 0.0F, 1.0F );
- red[i] = (GLint) (f * (GLfloat) red[i] + (1.0F-f) * fog_red);
- green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
- blue[i] = (GLint) (f * (GLfloat) blue[i] + (1.0F-f) * fog_blue);
- alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
- }
- break;
- case GL_EXP2:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = exp( -(CC.Fog.Density*CC.Fog.Density * eyez*eyez) );
- f = CLAMP( f, 0.0F, 1.0F );
- red[i] = (GLint) (f * (GLfloat) red[i] + (1.0F-f) * fog_red);
- green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
- blue[i] = (GLint) (f * (GLfloat) blue[i] + (1.0F-f) * fog_blue);
- alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
- }
- break;
- }
- }
-
-
-
-
- /*
- * Apply fog to an array of color index pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * index - pixel color indexes
- * Output: index - fogged pixel color indexes
- */
- void gl_fog_index_pixels( GLuint n, GLint z[], GLuint index[] )
- {
- /* TODO: optimize case when c = 1.0 and d = 0.0 */
- GLfloat d = CC.ProjectionMatrix[14];
- GLfloat c = CC.ProjectionMatrix[10];
- GLfloat winz, ndcz, eyez, f;
- GLuint i;
-
- switch (CC.Fog.Mode) {
- case GL_LINEAR:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = (CC.Fog.End - eyez) / (CC.Fog.End - CC.Fog.Start);
- f = CLAMP( f, 0.0F, 1.0F );
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
- }
- break;
- case GL_EXP:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = exp( -CC.Fog.Density * eyez );
- f = CLAMP( f, 0.0F, 1.0F );
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
- }
- break;
- case GL_EXP2:
- for (i=0;i<n;i++) {
- winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
- ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
- eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- f = exp( -(CC.Fog.Density*CC.Fog.Density * eyez*eyez) );
- f = CLAMP( f, 0.0F, 1.0F );
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
- }
- break;
- }
-
- }
-
-